class Wedge {
    constructor({
        type,
        angle = 0,
        opacity = 1,
        width = 0,
        height = 0,
        x = 0,
        y = 0,
        rotationCenterX = null,
        rotationCenterY = null,
        selectable = true,
        hasDeleteButton = true,
        hasResizeButton = true,
        hasEditButton = true,
        buttons = [],
        onClickEdit,
    } = {}) {
        this.type = type;
        this.angle = angle;
        this.opacity = opacity;
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
        this.isSelected = false;
        this.rotationCenterX = rotationCenterX !== null ? rotationCenterX : this.width / 2;
        this.rotationCenterY = rotationCenterY !== null ? rotationCenterY : this.height / 2;
        this.selectable = selectable;
        this.hasDeleteButton = hasDeleteButton;
        this.hasResizeButton = hasResizeButton;
        this.hasEditButton = hasEditButton;

        this.onClickEdit = onClickEdit;

        this.buttons = [];

        buttons.forEach((item) => {
            this.installButton(new ControlButton(item));
        });

        this._initializeButtons();
    }

    _initializeButtons() {
        console.log(this.buttons);
        let actionList = this.buttons.map((item) => {
            return item.action;
        });

        if (this.hasDeleteButton && !actionList.includes('delete')) {
            this.installButton(
                new ControlButton({
                    action: 'delete',
                    x: 0,
                    y: 0,
                    width: 20,
                    height: 20,
                    color: 'red',
                })
            );
        }

        if (this.hasResizeButton && !actionList.includes('resize')) {
            this.installButton(
                new ControlButton({
                    action: 'resize',
                    x: 1,
                    y: 1,
                    width: 20,
                    height: 20,
                    color: 'green',
                })
            );
        }

        if (this.hasEditButton && !actionList.includes('edit')) {
            this.installButton(
                new ControlButton({
                    action: 'edit',
                    x: 1,
                    y: 0,
                    width: 20,
                    height: 20,
                    color: 'yellow',
                    onClick: this.onClickEdit,
                })
            );
        }
    }

    installButton(button) {
        this.buttons.push(button);
    }

    render(context) {
        context.save();
        context.globalAlpha = this.opacity;

        // Move to the rotation center
        context.translate(this.x + this.rotationCenterX, this.y + this.rotationCenterY);

        // Rotate around the rotation center
        context.rotate((this.angle * Math.PI) / 180);

        // Move back and draw the object
        context.translate(-(this.x + this.rotationCenterX), -(this.y + this.rotationCenterY));
        this._render(context);
        context.restore();

        if (this.isSelected) {
            this._renderSelection(context);
        }
    }

    _render(context) {
        // To be implemented by subclasses
    }

    _renderSelection(context) {
        context.save();

        // Apply the same transformations for selection box and buttons
        context.translate(this.x + this.rotationCenterX, this.y + this.rotationCenterY);
        context.rotate((this.angle * Math.PI) / 180);
        context.translate(-(this.x + this.rotationCenterX), -(this.y + this.rotationCenterY));

        context.strokeStyle = 'blue';
        context.lineWidth = 2;
        context.strokeRect(this.x, this.y, this.width, this.height);

        this.buttons.forEach((button) => {
            button.render(context, this);
        });

        context.restore();
    }

    contains(x, y) {
        const rotatedPoint = this._rotatePoint(x, y, -this.angle); // 逆时针旋转回原始坐标系
        const localX = rotatedPoint.x - this.x;
        const localY = rotatedPoint.y - this.y;
        return localX >= 0 && localX <= this.width && localY >= 0 && localY <= this.height;
    }

    buttonContains(x, y) {
        const rotatedPoint = this._rotatePoint(x, y, -this.angle);

        for (let i = this.buttons.length - 1; i >= 0; i--) {
            const button = this.buttons[i];
            if (button.contains(rotatedPoint.x, rotatedPoint.y, this)) {
                typeof button.onClick === 'function' ? button.onClick() : null;
                return button;
            }
        }
        return null;
    }

    _rotatePoint(x, y, angle) {
        const radians = (angle * Math.PI) / 180;
        const centerX = this.x + this.rotationCenterX;
        const centerY = this.y + this.rotationCenterY;

        const cosTheta = Math.cos(radians);
        const sinTheta = Math.sin(radians);

        const deltaX = x - centerX;
        const deltaY = y - centerY;

        const rotatedX = centerX + deltaX * cosTheta - deltaY * sinTheta;
        const rotatedY = centerY + deltaX * sinTheta + deltaY * cosTheta;

        return { x: rotatedX, y: rotatedY };
    }

    updateRotationCenter(newWidth, newHeight) {
        // 保持宽高比不变
        const aspectRatio = this.width / this.height;
        if (newWidth / newHeight > aspectRatio) {
            newWidth = newHeight * aspectRatio;
        } else {
            newHeight = newWidth / aspectRatio;
        }

        const widthRatio = newWidth / this.width;
        const heightRatio = newHeight / this.height;

        const newRotationCenterX = this.rotationCenterX * widthRatio;
        const newRotationCenterY = this.rotationCenterY * heightRatio;

        const deltaX = this.rotationCenterX - newRotationCenterX;
        const deltaY = this.rotationCenterY - newRotationCenterY;

        this.x += deltaX;
        this.y += deltaY;

        this.width = newWidth;
        this.height = newHeight;
        this.rotationCenterX = newRotationCenterX;
        this.rotationCenterY = newRotationCenterY;
    }

    setSelectable(selectable) {
        this.selectable = selectable;
    }

    isSelectable() {
        return this.selectable;
    }
}
